/*
 * memoire.c
 * projet Unix: 6 qui prend
 *
 *  @authors Doublier Sami
 *  @authors Pingot Alexandre
 */

#include "memoire.h"

void lecteur(sharedMem * player_mem, sharedMem * memory,
		sharedCounter* counterMem, int semaSetID) {

	/* Demande de "lock" du compteur de processus de lecture. */
	semDown(semaSetID, MUTEX);

	counterMem->lecteurs = counterMem->lecteurs + 1;

	/* "Lock" la mémoire partagée afin de donner l'accès exclusif au premier lecteur. */
	if (counterMem->lecteurs == 1)
		semDown(semaSetID, DB);

	/* "Unlock" du compteur de processus de lecture. */
	semUp(semaSetID, MUTEX);

	/* Recopie la mémoire de la section critique dans la mémoire des joueurs. */
	ecrireMemoire(memory, player_mem);

	/* Demande de "lock" du compteur de processus de lecture. */
	semDown(semaSetID, MUTEX);
	counterMem->lecteurs = counterMem->lecteurs - 1;

	/* "Unlock" de la mémoire partagée si on est le dernier lecteur. */
	if (counterMem->lecteurs == 0)
		semUp(semaSetID, DB); /* On libère l'accès à la mémoire partagée pour le redacteur. */

	/* "Unlock" du compteur de processus de lecture. */
	semUp(semaSetID, MUTEX);
}

void afficherMemoire(sharedMem * memory) {
	int i, j;
	int nbJoueur = memory->joueurs;

	if(nbJoueur > 1){
		printf("%d joueurs sont en ligne.\n", nbJoueur);
	}else{
		printf("Vous êtes le seul joueur connecté.");
	}

	for(i = 0; i< MAX_JOUEURS; i++){
		printf("score du joueur %d : %3d",(i+1),memory->totaux_points[i]);
	}

	for (i = 0; i < MAX_JOUEURS; i++) {
		printf("\nNom: %s \nCartes en main :\n", memory->nom[i]);
		for (j = 0; j < MAX_CARTES_PAR_JOUEUR; j++) {
			printf("%3d : ", memory->visible[i][j]);
		}
	}

	printf("Cartes sur la tables\n");
	for (i = 0; i < CARTES_LIGNE; i++) {
		for (j = 0; j < CARTES_COLONNE; j++) {
			printf("%3d : ", memory->cartesSurLaTable[i][j]);
		}
		printf("\n");
	}
}

void ecrireMemoire(sharedMem * serv_mem, sharedMem * memory) {
	int i, j;

	memory->joueurs = serv_mem->joueurs;

	for (i = 0; i < MAX_JOUEURS; i++) {
		strcpy(memory->nom[i], serv_mem->nom[i]);
		for (j = 0; j < MAX_CARTES_PAR_JOUEUR; j++) {
			memory->visible[i][j] = serv_mem->visible[i][j];
		}
	}

	for (i = 0; i < CARTES_LIGNE; i++) {
		for (j = 0; j < CARTES_COLONNE; j++) {
			memory->cartesSurLaTable[i][j] = serv_mem->cartesSurLaTable[i][j];

		}
	}

}

/* utilise par le serveur
 * serv_mem = memoire reçue à sauver
 * memory = memoire où il faut écrire
 * */
void redacteur(sharedMem * serv_mem, sharedMem * memory, int semaSetID) {
	/* "Lock" de la mémoire partagée afin d'en avoir l'accès exclusif */

	semDown(semaSetID, DB);

	/* Section critique */
	/* on peut commencer à ecrire */
	ecrireMemoire(serv_mem, memory);

	/* afficherMemoire(memory); */

	/* "Unlock" de la mémoire partagée */
	semUp(semaSetID, DB);
}

int shmInit(key_t key, size_t size) {
	int shmid;

	/*  Creation du segment */
	SYSS(shmid = shmget(key, size, IPC_CREAT | 0666));
	return shmid;
}

char* shmAttach(int shmId, char * addr) {

	/* On attache l'adresse au segment de la memoire et on la renvoie */
	SYSM(addr = shmat(shmId, NULL, 0));
	return addr;
}
